home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / mp / mp2.c < prev    next >
C/C++ Source or Header  |  1991-02-13  |  10KB  |  620 lines

  1.  
  2. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  3. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  4. /*~                                    ~*/
  5. /*~               OPERATIONS DE BASE (NOYAU)            ~*/
  6. /*~             Functions which can be efficient in plain C             ~*/
  7. /*~                                    ~*/
  8. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  9. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  10.  
  11.  
  12. #include "config.h"
  13. #include "genpari.h"
  14. #include "arith.h"
  15.  
  16. /* -2147483648 */
  17.  
  18. ulong MOST_NEGS[3]={0x01ff0003, 0xff000003,1<<31};
  19.  
  20. /* +2147483648 */
  21.  
  22. ulong ABS_MOST_NEGS[3]={0x01ff0003, 0x01000003,1<<31};
  23.  
  24.  
  25. GEN stoi(x)
  26.      long x;
  27. {
  28.   GEN y;
  29.   
  30.   if(!x) return gzero;
  31.   y=cgeti(3);
  32.   if(x>0) {y[1]=0x1000003;y[2]=x;}
  33.   else{y[1]=0xff000003;y[2]= -x;}
  34.   return y;
  35. }
  36.  
  37.  
  38. GEN cgetg(x,y)
  39.      long x,y;
  40. {
  41.   unsigned long p1;
  42.   GEN z;
  43.   
  44.   p1=avma-(((unsigned short)x)<<2);if(p1<bot) err(errpile);
  45.   avma=p1;z=(GEN)p1;z[0]=0x10000+x+(y<<24);
  46.   return z;
  47. }
  48.  
  49.  
  50. GEN cgeti(x)
  51.      long x;
  52. {
  53.   unsigned long p1;
  54.   GEN z;
  55.   
  56.   p1=avma-4*x;if(p1<bot) err(errpile);
  57.   avma=p1;z=(GEN)p1;z[0]=0x1010000+x;
  58.   return z;
  59. }
  60.  
  61.  
  62. GEN icopy(x)
  63.      GEN x;
  64. {
  65.   GEN y;
  66.   long lx=lgef(x),i;
  67.   
  68.   y=cgeti(lx);
  69.   for(i=1;i<lx;i++) y[i]=x[i];
  70.   return y;
  71. }
  72.  
  73.  
  74. GEN negi(x)
  75.      GEN x;
  76. {
  77.   long s=signe(x);
  78.   GEN y;
  79.   
  80.   if(!s) return gzero;
  81.   y=icopy(x);setsigne(y,-s);
  82.   return y;
  83. }
  84.  
  85.  
  86. GEN absi(x)
  87.      GEN x;
  88. {
  89.   GEN y;
  90.   long s=signe(x);
  91.   
  92.   if(!s) return gzero;
  93.   y=icopy(x);setsigne(y,1);return y;
  94. }
  95.  
  96.  
  97. long itos(x)
  98.      GEN x;
  99. {
  100.   long s=signe(x),p2;
  101.   unsigned long p1;
  102.   
  103.   if(!s) return 0;
  104.   if(lgef(x)>3) err(affer2);
  105.   p1=x[2];if(p1>=0x80000000) err(affer2);
  106.   p2=(s>0)?p1:(-((long)p1));return p2;
  107. }
  108.  
  109.  
  110. void affsi(s,x)
  111.      long s;
  112.      GEN x;
  113. {
  114.   long lx;
  115.   
  116.   if(!s) {x[1]=2;return;}
  117.   lx=lg(x);if(lx<3) err(affer1);
  118.   if(s>0) {x[1]=0x1000003;x[2]=s;}
  119.   else { s = -s;
  120.      if (s < 0) /* s = -2^31 */
  121.        { if(lx<4) err(affer1);
  122.          x[1]=0xff000004;
  123.          x[2]= 0;
  124.          x[3]= 1;
  125.        }
  126.        else 
  127.          {x[1]=0xff000003;x[2]= s;}
  128.   }
  129. }
  130.  
  131.  
  132. void affii(x,y)
  133.      GEN x,y;
  134. {
  135.   long lx=lgef(x),i;
  136.   
  137.   if(x==y) return;
  138.   if(lg(y)<lx) err(affer3);
  139.   for(i=1;i<lx;i++) y[i]=x[i];
  140. }
  141.  
  142.  
  143. GEN shifts(x,y)
  144.      long x,y;
  145. {
  146.   long t[3];
  147.   
  148.   if(!x) return gzero;
  149.   t[0]=0x1010003;
  150.   if(x>0) {t[1]=0x1000003;t[2]=x;}
  151.   else {t[1]=0xff000003;t[2]= -x;}
  152.   return shifti(t,y);
  153. }
  154.  
  155.  
  156. GEN shifti(x,n)
  157.      GEN x;
  158.      long n;
  159.   long lx=lgef(x),i,s=signe(x),d,m,p1,p2,k;
  160.   GEN y; TEMPVARS
  161.   ulong hiremainder;
  162.   
  163.   if(!s) return gzero;
  164.   if(!n) return icopy(x);
  165.   if(n>0)
  166.     {
  167.       d=n>>5;m=n&31;
  168.       if(m)
  169.     {
  170.       p1=shiftl(x[2],m);p2=hiremainder;k=0;
  171.       if(p2)
  172.         {
  173.           y=cgeti(lx+d+1);for(i=lx+1;i<=lx+d;i++) y[i]=0;
  174.           for(i=lx;i>=4;i--) {y[i]=shiftl(x[i-1],m)+k;k=hiremainder;}
  175.           y[3]=p1+k;y[2]=p2;
  176.         }
  177.       else
  178.         {
  179.           y=cgeti(lx+d);for(i=lx;i<lx+d;i++) y[i]=0;
  180.           for(i=lx-1;i>=3;i--) {y[i]=shiftl(x[i],m)+k;k=hiremainder;}
  181.           y[2]=p1+k;
  182.         }
  183.     }
  184.       else
  185.     {
  186.       y=cgeti(lx+d);for(i=lx;i<lx+d;i++) y[i]=0;
  187.       for(i=lx-1;i>=2;i--) y[i]=x[i];
  188.     }
  189.     }
  190.   else
  191.     {
  192.       n= -n;d=n>>5;m=n&31;if(lx<d+3) return gzero;
  193.       if(!m)
  194.     {
  195.       y=cgeti(lx-d);for(i=2;i<lx-d;i++) y[i]=x[i];
  196.     }
  197.       else 
  198.     {
  199.       m=32-m;d++;
  200.       p1=shiftl(x[2],m);
  201.       if(hiremainder)
  202.         {
  203.           y=cgeti(lx-d+1);y[2]=hiremainder;
  204.           for(i=3;i<=lx-d;i++)
  205.         {
  206.           p2=shiftl(x[i],m);y[i]=p1+hiremainder;p1=p2;
  207.         }
  208.         }
  209.       else
  210.         {
  211.           if(lx==d+2) return gzero;
  212.           y=cgeti(lx-d);
  213.           for(i=3;i<=lx-d;i++) 
  214.         {
  215.           p2=shiftl(x[i],m);y[i-1]=p1+hiremainder;p1=p2;
  216.         }
  217.         }
  218.     }
  219.     }   
  220.   y[1]=y[0];setsigne(y,s);return y;
  221. }
  222.  
  223.  
  224. GEN mptrunc(x)
  225.      GEN x;
  226. {
  227.   long e,i,s,lx=lg(x),p1,p2,m;
  228.   unsigned long d; TEMPVARS
  229.   GEN y;ulong hiremainder;
  230.   
  231.   if(typ(x)==1) return icopy(x);
  232.   s=signe(x);if(!s) return gzero;
  233.   e=expo(x);if(e<0) return gzero;
  234.   d=e>>5;m=e&31;if(d>=lx-2) err(truer2);
  235.   y=cgeti(d+3);y[1]=y[0];setsigne(y,s);
  236.   if(m==31) for(i=2;i<=d+2;i++) y[i]=x[i];
  237.   else
  238.     {
  239.       m++;p1=0;
  240.       for(i=2;i<=d+2;i++)
  241.     {
  242.       p2=shiftl(x[i],m);y[i]=hiremainder+p1;p1=p2;
  243.     }
  244.     }
  245.   return y;
  246. }
  247.  
  248.  
  249. GEN mpent(x)
  250.      GEN x;
  251. {
  252.   long e,i,lx=lg(x),m,f,p1,p2;
  253.   unsigned long d;ulong hiremainder;
  254.   GEN y,z; TEMPVARS
  255.   
  256.   if(typ(x)==1) return icopy(x);
  257.   if(signe(x)>=0) return mptrunc(x);
  258.   e=expo(x);if(e<0) {y=cgeti(3);y[2]=1;y[1]=0xff000003;return y;}
  259.   d=e>>5;m=e&31;if(d>=lx-2) err(truer2);
  260.   y=cgeti(d+3);y[1]=0xff000003+d;
  261.   if(m==31) 
  262.     {
  263.       for(i=2;i<=d+2;i++) y[i]=x[i];
  264.       while((i<lx)&&(!x[i])) i++;
  265.       f=(i<lx);
  266.     }    
  267.   else
  268.     {
  269.       m++;p1=0;
  270.       for(i=2;i<=d+2;i++)
  271.     {
  272.       p2=shiftl(x[i],m);y[i]=hiremainder+p1;p1=p2;
  273.     }
  274.       if(p1) f=1;
  275.       else
  276.     {
  277.       while((i<lx)&&(!x[i])) i++;
  278.       f=(i<lx);
  279.     }
  280.     }
  281.   if(f)
  282.     {
  283.       for(i=d+2;(i>=2)&&(y[i]==0xffffffff);i--) y[i]=0;
  284.       if(i>=2) y[i]++;
  285.       else
  286.     {
  287.       z=y;y=cgeti(1);*y=(*z)+1;y[1]=z[1]+1;
  288.     }
  289.     }
  290.   return y;
  291. }
  292.  
  293.  
  294. int cmpsi(x,y)
  295.      long x;
  296.      GEN y;
  297. {
  298.   ulong p;
  299.   
  300.   if(!x) return -signe(y);
  301.   if(x>0)
  302.     {
  303.       if(signe(y)<=0) return 1;
  304.       if(lgef(y)>3) return -1;
  305.       p=y[2];if(p==x) return 0;
  306.       return (p<(ulong)x) ? 1 : -1;
  307.     }
  308.   else
  309.     {  /* x <= 0 */
  310.       if(signe(y)>=0) return -1;
  311.       if(lgef(y)>3)
  312.     { if (-x < 0)
  313.         { /* x = -2^31 */
  314.           if (lgef(y)==4 &&
  315.           y[2] == 0 &&
  316.           y[3] == 1)
  317.         return 0;
  318.         else
  319.           return 1;}}
  320.       p=y[2];if(p== -x) return 0;
  321.       return (p<(ulong)(-x)) ? -1 : 1;
  322.     }
  323. }
  324.  
  325.  
  326. int cmpii(x,y)
  327.      GEN x,y;
  328. {
  329.   long sx=signe(x),sy=signe(y),lx,ly,i;
  330.   
  331.   if(sx<sy) return -1;
  332.   if(sx>sy) return 1;
  333.   if(!sx) return 0;
  334.   lx=lgef(x);ly=lgef(y);
  335.   if(lx>ly) return sx;
  336.   if(lx<ly) return -sx;
  337.   for(i=2;(i<lx)&&(x[i]==y[i]);i++);
  338.   if(i==lx) return 0;
  339.   return ((ulong)x[i]>(ulong)y[i]) ? sx : -sx;
  340. }
  341.  
  342.  
  343. GEN addss(x,y)
  344.      long x,y;
  345. {
  346.   long t[3];
  347.   
  348.   if(!x) return stoi(y);
  349.   t[0]=0x1010003;
  350.   if(x>0) {t[1]=0x1000003;t[2]=x;} else {t[1]=0xff000003;t[2]= -x;}
  351.   return addsi(y,t);
  352. }
  353.  
  354.  
  355. GEN subii(x,y)
  356.      GEN x,y;
  357. {
  358.   long s=signe(y);
  359.   GEN z;
  360.   
  361.   if(x==y) return gzero;
  362.   setsigne(y,-s);z=addii(x,y);setsigne(y,s);
  363.   return z;
  364. }
  365.  
  366.  
  367. GEN subsi(x,y)
  368.      long x;
  369.      GEN y;
  370. {
  371.   long s=signe(y);
  372.   GEN z;
  373.   
  374.   setsigne(y,-s);z=addsi(x,y);setsigne(y,s);return z;
  375. }
  376.  
  377.  
  378. GEN subss(x,y)
  379.      long x,y;
  380. {
  381.   if (y == (1<<31))
  382.     return addsi(x,ABS_MOST_NEGS);
  383.   return addss(-y,x);
  384. }
  385.  
  386.  
  387. GEN convi(x)
  388.      GEN x;
  389. {
  390.   long lx,av=avma,lz;
  391.   GEN z,p1,p2;  
  392.   
  393.   if(!signe(x))
  394.     {
  395.       z=cgeti(3);z[1]= -1;z[2]=0;avma=av;return z+3;
  396.     }
  397.   p1=absi(x);lx=lgef(p1);lz=((lx-2)*15)/14+3;z=cgeti(lz);z[1]= -1;
  398.   for(p2=z+2;signe(p1);p2++) *p2=divisii(p1,1000000000,p1);
  399.   avma=av;return p2;
  400. }
  401.  
  402.  
  403.  
  404. void mulsii(x,y,z)
  405.      long x;
  406.      GEN y,z;
  407. {
  408.   long av=avma;
  409.   GEN p1;
  410.   
  411.   p1=mulsi(x,y);affii(p1,z);avma=av;
  412. }
  413.  
  414.  
  415. void addsii(x,y,z)
  416.      long x;
  417.      GEN y,z;
  418. {
  419.   long av=avma;
  420.   GEN p1;
  421.   
  422.   p1=addsi(x,y);affii(p1,z);avma=av;
  423. }
  424.  
  425.  
  426. long divisii(x,y,z)
  427.      long y;
  428.      GEN x,z;
  429. {
  430.   long av=avma,k;
  431.   GEN p1;
  432.   
  433.   p1=divis(x,y);affii(p1,z);avma=av;
  434.   k=hiremainder;return k;
  435. }
  436.  
  437.  
  438. long vals(x)
  439.      long x;
  440. {
  441.   unsigned short int y,z;
  442.   int s;
  443.  
  444.   if(!x) return -1;
  445.   y=x;if(!y) {s=16;y=((ulong)x)>>16;} else s=0;
  446.   z=y&255;if(!z) {s+=8;z=y>>8;}
  447.   y=z&15;if(!y) {s+=4;y=z>>4;}
  448.   z=y&3;if(!z) {s+=2;z=y>>2;}
  449.   return (z&1) ? s : s+1;
  450. }
  451.  
  452.  
  453. long vali(x)
  454.      GEN x;
  455. {
  456.   long i,lx=lgef(x);
  457.   
  458.   if(!signe(x)) return -1;
  459.   for(i=lx-1;(i>=2)&&(!x[i]);i--);
  460.   return ((lx-1-i)<<5)+vals(x[i]);
  461. }
  462.  
  463. GEN dvmdss(x,y,z)
  464.      long x,y;
  465.      GEN *z;
  466. {
  467.   GEN p1;
  468.  
  469.   p1=divss(x,y);*z=stoi(hiremainder);
  470.   return p1;
  471. }
  472.  
  473.  
  474. GEN dvmdsi(x,y,z)
  475.      long x;
  476.      GEN y,*z;
  477. {
  478.   GEN p1;
  479.   p1=divsi(x,y);*z=stoi(hiremainder);
  480.   return p1;
  481. }
  482.  
  483.  
  484. GEN dvmdis(x,y,z)
  485.      long y;
  486.      GEN x,*z;
  487. {
  488.   GEN p1;
  489.   p1=divis(x,y);*z=stoi(hiremainder);
  490.   return p1;
  491. }
  492.  
  493.  
  494. GEN ressi(x,y)
  495.      long x;
  496.      GEN y;
  497.   divsi(x,y);return stoi(hiremainder);
  498. }
  499.  
  500.  
  501. GEN modsi(x,y)
  502.      long x;
  503.      GEN y;
  504. {
  505.   long s;
  506.   GEN p1;
  507.   
  508.   divsi(x,y);
  509.   if(!hiremainder) return gzero;
  510.   if(x>0) return stoi(hiremainder);
  511.   else
  512.     {
  513.       s=signe(y);setsigne(y,1);p1=addsi(hiremainder,y);
  514.       setsigne(y,s);return p1;
  515.     }
  516. }
  517.  
  518.  
  519. GEN modis(x,y)
  520.      long y;
  521.      GEN x;
  522.   divis(x,y);if(!hiremainder) return gzero;
  523.   return (signe(x)>0) ? stoi(hiremainder) : stoi(abs(y)+hiremainder);
  524. }
  525.  
  526.  
  527. GEN resis(x,y)
  528.      long y;
  529.      GEN x;
  530.   divis(x,y);return stoi(hiremainder);
  531. }
  532.  
  533.  
  534. GEN modii(x,y)
  535.      GEN x,y;
  536. {
  537.   long av=avma,tetpil;
  538.   GEN p1;
  539.  
  540.   p1=dvmdii(x,y,-1);
  541.   if(signe(p1)>=0) return p1;
  542.   tetpil=avma;p1=(signe(y)>0) ? addii(p1,y) : subii(p1,y);
  543.   return gerepile(av,tetpil,p1);
  544. }
  545.  
  546.  
  547. mpdivis(x,y,z)
  548.      GEN x,y,z;
  549. {
  550.   long av=avma;
  551.   GEN p1,p2;
  552.  
  553.   p1=dvmdii(x,y,&p2);
  554.   if(signe(p2)) {avma=av;return 0;}
  555.   affii(p1,z);avma=av;return 1;
  556. }
  557.  
  558.  
  559. divise(x,y)
  560.      GEN x,y;
  561. {
  562.   long av=avma;
  563.   GEN p1;
  564.  
  565.   p1=dvmdii(x,y,-1);avma=av;
  566.   return signe(p1) ? 0 : 1;
  567. }
  568.  
  569.  
  570. GEN gerepile(l,p,q)
  571.     GEN l,p,q;
  572.  
  573. {
  574.   long av,declg,tl;
  575.   GEN ll,pp,l1,l2,l3;
  576.  
  577.   declg=(long)l-(long)p;if(declg<=0) return q;
  578.   for(ll=l,pp=p;pp>(GEN)avma;) *--ll= *--pp;
  579.   av=(long)ll;
  580.   while((ll<l)||((ll==l)&&(long)q))
  581.   {
  582.     l2=ll+lontyp[tl=typ(ll)];
  583.     if(tl==10) {l3=ll+lgef(ll);ll+=lg(ll);if(l3>ll) l3=l2;}
  584.     else {ll+=lg(ll);l3=ll;} 
  585.     for(;l2<l3;l2++) 
  586. /*    for(;l2<ll;l2++) */
  587.       {
  588.     l1=(GEN)(*l2);
  589.     if((l1<l)&&(l1>=(GEN)avma))
  590.       {
  591.         if(l1<p) *l2+=declg;
  592.         else
  593.           if(ll<=l) err(gerper);
  594.       }
  595.       }
  596.   }
  597.   if((!((long)q))||((q<p)&&(q>=(GEN)avma)))
  598.   {
  599.     avma=av;return q+(declg>>2);
  600.   }
  601.   else {avma=av;return q;}
  602. }
  603.  
  604.  
  605. void cgiv(x)
  606.      GEN x;
  607. {
  608.   long p;
  609.  
  610.   if((p=pere(x))==255) return;
  611.   if((x!=(GEN)avma)||(p>1)) {setpere(x,p-1);return;}
  612.   do x+=lg(x);while(!pere(x));
  613.   avma=(long)x;
  614.   return;
  615. }
  616.